#include "msgqueue.h"
static int messageId = 0;//消息队列ID
static const char messagePath[50] = "/home/softeem/softeem/AdressBook/Message";
/*
    参数：
        srm 接收消息体的地址
    功能：接收消息队列
    返回值：
        接收成功 0 失败 -1;
*/
int Recive(ServerRcvMsg *srm)
{
    int res = -1, size = 0;
    memset(srm, 0, sizeof(ServerRcvMsg));
    size = sizeof(ServerRcvMsg) - sizeof(long);
    res = msgrcv(messageId, srm, size, SERVER, 0);
    return res;
}

/*
    参数：
        messageId 消息队列id的地址
    功能：删除消息队列
*/
void ClearMsgQ()
{
    msgctl(messageId, IPC_RMID, NULL);
}


/*
    参数：
        messageId 消息队列id的地址
    功能：创建消息队列
    返回值：
        创建成功 0 失败 -1;
*/
int CreateMsgQ()
{
    //创建打开文件
    int fd = open(messagePath, O_RDONLY|O_CREAT,0666);
	if(-1 == fd)
	{
		return -1;
	}
	close(fd);

	//创建key
	int key = ftok(messagePath, 'a');
	if(key == -1)
	{
		perror("ftok error\n");
		return -1;
	}

	//创建或打开消息队列
	messageId = msgget(key, IPC_CREAT|IPC_EXCL|0666);
	if(messageId == -1)
	{
		if(errno == EEXIST)
		{
			messageId = msgget(key, 0666);//打开
		}
		else
		{
			perror("msgget err\n");
			return -1;
		}
	}
    return 0;
}

/*
    参数： 用户信息
    功能：  向进程B获取用户的联系人列表
*/
void RequsetGetContactList(PUserType pUser, PSeqListType pContactList)
{
    int res = 0, size = 0;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.argVal.userInfo.userId = pUser->userId;
    csm.handle = GETCONTACTLIST;//0
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return;
    }

    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    while(1)
    {
        res = msgrcv(messageId, &crm, size, pUser->userId, 0);
        if(res == -1 || crm.result == -1)
        {
            return;
        }
        if(crm.result == 0)//操作成功
        {
            break;
        }
        else if(crm.result == 1)
        {
            InsertIntoSeqlist(pContactList, pContactList->last + 1, crm.resultVal);
        }
    }
}

/*
    参数： 联系人列表空间地址
    功能： 响应进程A用户的获取联系人列表请求
*/
void ResponseGetContactList(long userId ,PSeqListType pContactList)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    size = sizeof(ssm) - sizeof(long);

    if(pContactList == NULL)
    {
        memset(&ssm, 0, sizeof(ssm));
        ssm.type = userId;
        ssm.result = -1;
        res = msgsnd(messageId, &ssm, size, 0);
    }
    else
    {
        for(int i = 0; i <= pContactList->last; i++)
        {
            memset(&ssm, 0, sizeof(ssm));
            ssm.type = userId;
            ssm.result = 1;
            ssm.resultVal = pContactList->data[i];
            res = msgsnd(messageId, &ssm, size, 0);
        }
        memset(&ssm, 0, sizeof(ssm));
        ssm.type = userId;
        ssm.result = 0;
        res = msgsnd(messageId, &ssm, size, 0);
    }
}

//添加联系人
//-1 程序异常
// 0  添加成功
int RequestAddContact(PElementType pData)
{
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = ADDCONTACT;//1
    csm.argVal.contactInfo = pData->contactInfo;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pData->contactInfo.userId, 0);
    if(res == -1 || crm.result == -1)
    {
        return -1;
    }
    if(crm.result == 0)//操作成功
    {
        //返回数据
        result = 0;
    }
    return result;
}

/*
    参数： 结果
    功能： 响应进程A添加联系人请求
*/
void ResponseAddContact(long userId, int result)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);
}

/*
    参数：
        pUser 用户信息空间地址
        pContactList 
    功能：访问登录
    返回值：
        0  登录成功
        -1 程序异常
        1  用户不存在
        2  重复登录
        3  密码不正确
*/
int RequestLogin(PUserType pUser)
{	
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;
    
    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = LOGIN;//2
    csm.argVal.userInfo = *pUser;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pUser->userId, 0);
    if(res == -1)
    {
        return -1;
    }
    if(crm.result == 0)//操作成功
    {
        //返回数据
        *pUser = crm.resultVal.userInfo;
    }

    //代码的重构 充分测试以后进行重新整理代码格式
    return crm.result;
}

/*
    参数：
        pUser 用户信息空间地址
        result
            0  登录成功
            -1 程序异常
            1  用户不存在
            2  重复登录
            3  密码不正确
    功能：响应访问登录
*/
void ResponseLogin(long userId, int result, PUserType pUser)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    if(pUser != NULL)
    {
        ssm.resultVal.userInfo = *pUser;
    }
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);
}

/*
    参数：
        pUser 用户信息空间地址
    功能：访问注册
    返回值：
        0  注册成功
        -1 程序异常
        1  用户存在 
        2  注册失败
*/
int RequestRegister(PUserType pUser)
{
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = REGISTER;//3 REGISTER
    csm.argVal.userInfo = *pUser;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pUser->userId, 0);
    if(res == -1)
    {
        return -1;
    }
    
    return crm.result;
}

/*
    参数：
    result： 
        0  注册成功
        -1 程序异常
        1  用户存在 
        2  注册失败
    功能：响应注册 
*/
void ResponseRegister(long userId, int result)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);//如果失败 -1 写日志 

}

// 参数： userId
// 功能：用户登出
// 返回值：成功 1， 失败 -1
int RequestLogout(PUserType pUser)
{
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = LOGOUT;//4 LOGOUT
    csm.argVal.userInfo = *pUser;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pUser->userId, 0);
    if(res == -1)
    {
        return -1;
    }
    if(crm.result == 0)//操作成功
    {
        //返回数据
        pUser->state = 0;
        return 1;
    }
    return crm.result;
}

/*
    参数：
        userId
        result
            -1 失败
            1  成功
    功能：响应登出
*/
void ResponseLogout(long userId,  int result)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);
}

// 参数： userId
// 功能：注消用户
// 返回值：成功 1， 失败 -1
int RequestDestroy(PUserType pUser)
{
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = DESTROY;//5 DESTROY
    csm.argVal.userInfo = *pUser;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pUser->userId, 0);
    if(res == -1)
    {
        return -1;
    }
    return crm.result;
}

// -1 程序异常
// 1  注销成功
// 响应退出帐号
void ResponseDestroy(long userId,  int result)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);

}

// 1）发送删除联系人信息请求
//-1 程序异常
// 0  删除成功
int RequestDeleteContact(PContactType pContact)
{
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = DELETECONTACT;//6 DELETECONTACT
    csm.argVal.contactInfo = *pContact;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pContact->userId, 0);
    if(res == -1)
    {
        return -1;
    }
    return crm.result;
}

// 1）响应删除联系人信息请求
//-1 程序异常
// 0  添加成功
void ResponseDeleteContact(long userId,  int result)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);
}

// 1）发送修改联系人信息请求	
//-1 程序异常
// 0  修改成功
int RequestChangeContact(PContactType pContact)
{
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = CHANGECONTACT;//7 CHANGECONTACT
    csm.argVal.contactInfo = *pContact;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pContact->userId, 0);
    if(res == -1)
    {
        return -1;
    }
    return crm.result;
}

// 1）发送修改联系人信息请求	
//-1 程序异常
// 0  添加成功
void ResponseChangeContact(long userId,  int result)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);
}

/*
	功能：在通讯录中清空联系人
	参数：
        pUser           用户信息空间地址
	返回值：
        -1 程序异常
        0  清空成功
*/
int RequestClearContact(PUserType pUser)
{
    // 1》向进程B发送添加联系人请求
    int res = 0, size = 0, result = -1;

    //发送消息，谁做了什么操作，有没有带数据
    ClientSendMsg csm = {};//客户端发送消息
    csm.type = SERVER;//消息类型
    csm.handle = CLEARCONTACT;//8 CLEARCONTACT
    csm.argVal.userInfo = *pUser;
    size = sizeof(csm) - sizeof(long);
    res = msgsnd(messageId, &csm, size, 0);
    if(res == -1)
    {
        return -1;
    }
    
    //接受消息, 操作是否成功，有没有返回数据
    ClientRcvMsg crm = {};//客户端接收消息
    size = sizeof(crm) - sizeof(long);
    res = msgrcv(messageId, &crm, size, pUser->userId, 0);
    if(res == -1)
    {
        return -1;
    }
    return crm.result;
}

/*
	功能：在通讯录中清空联系人
	参数：
        userId           用户ID
        result
            -1 程序异常
            0  清空成功
        
*/
void ResponseClearContact(long userId,  int result)
{
    int res = 0,size = 0;

    //发送消息, 操作是否成功，有没有返回数据
    ServerSendMsg ssm = {};//服务端发送消息
    ssm.type = userId;
    ssm.result = result;
    size = sizeof(ServerSendMsg) - sizeof(long);
    res = msgsnd(messageId, &ssm, size, 0);
}